/* SVN FILE: $Id: validation.js 24 2008-07-09 13:04:44Z celobandster $ */
/**
* Application : The Javascript MVC Framework
*
* @package application.core
* @subpackage cookie
* @author 			$Author: celobandster $
* @copyright 		(c) Rafael Bandeira, Marcelo Condotta, Henrique Condotta. All Rights Reserved.
* @version 			$Revision: 24 $
* @lastrevision 	$Date: 2008-07-09 13:04:44 +0000 (Wed, 09 Jul 2008) $
* @modifiedby 		$LastChangedBy: celobandster $
* @lastmodified 	$LastChangedDate: 2008-07-09 13:04:44 +0000 (Wed, 09 Jul 2008) $
* @license 			The MIT License [http://www.opensource.org/licenses/mit-license.php]
* @filesource 		$URL: http://jsmvcapplication.googlecode.com/svn/trunk/application/src/core/validation.js $
*/

var Validation = new Object(
{
	getExpression : function(value, type)
	{
		if (Object.isUndefined(type))
			return Validation.Expressions[value];
		else
			return Validation.Expressions[value][type];
	},
	empty : function(value)
	{
		return [undefined,null,'',' ',0,[]].include(value);
	},
	email : function(value)
	{
		expression = this.getExpression('email');
		return expression.test(value); 
	},
	alphaNumeric : function(value)
	{
		expression = this.getExpression('alphaNumeric');
		return expression.test(value); 
	},
	url : function(value)
	{
		expression = this.getExpression('url');
		return expression.test(value); 
	},
	phone : function(value)
	{
		expression = this.getExpression('phone');
		return expression.test(value); 
	},
	between : function(value, min, max)
	{
		size = value.length;
		if (size < min || size > max)
			return false;
		else
			return true;
	},
	cc : function(value, type)
	{
		if (Object.isUndefined(type)) type = 'any';
		if (value.length < 13)
			return false;
		expression = this.getExpression('cc', type);
		return expression.test(value); 
	},
	comparison : function(value1, operator, value2)
	{
		operator = operator.toLowerCase().replace(/ |\t|\n|\r|\0|\x0B/g, "");
		ret = false;
		switch(operator)
		{
			case 'isgreater':
			case '>':
				if (value1 > value2)
					ret = true;
			break;
			case 'isless':
			case '<':
				if (value1 < value2)
					ret = true;
			break;
			case 'greaterorequal':
			case '>=':
				if (value1 >= value2)
					ret = true;
			break;
			case 'lessorequal':
			case '<=':
				if (value1 <= value2)
					ret = true;
			break;
			case 'equalto':
			case '==':
				if (value1 == value2)
					ret = true;
			break;
			case 'notequal':
			case '!=':
				if (value1 != value2)
					ret = true;
			break;
		}
		return ret;
	},
	custom : function(value, regex)
	{
		if (typeof regex != 'object') 
			regexp = new RegExp(regex);
		else 
			regexp = regex;
		return regexp.test(value);
	},
	date : function(value, format, regex)
	{
		if (!Object.isUndefined(regex))
			return regex.test(value);
		if (Object.isUndefined(format)) format = 'ymd';

		expression = this.getExpression('date', format);
		return expression.test(value);
	},
	time : function(value)
	{
		expression = this.getExpression('time');
		return expression.test(value); 
	},
	boolean : function(value)
	{
		expression = new Array(0,1,'0','1',true,false);
		return expression.include(value); 
	},
	decimal : function(value, float)
	{
		if (!Object.isUndefined(float))
			expression = new RegExp('^[\-+]?[0-9]*\.{1}[0-9]{'+float+'}$');
		else
			expression = this.getExpression('decimal');
		return expression.test(value);
	},
	equalTo : function(value1, value2)
	{
		return (value1 === value2); 
	},
	extension : function(value, extensions)
	{
		if (Object.isString(extensions))
		{
			switch (extensions)
			{
				case 'image':
				case 'img':
					ext = new Array('gif','png','jpg','jpeg','bmp');
				break;
				case 'document':
					ext = new Array('doc','pdf','txt','rtf','docx');
				break;
				default:
					ext = new Array(extensions.toLowerCase());
				break;
			}
		}
		else
			ext = extensions.invoke('toLowerCase');
		
		if (Object.isArray(value))
		{
			value.each(function(val)
			{
				if (Validation.extension(val, ext) == false)
					return false;
			});
			return true;
		}
		value = value.substr(value.lastIndexOf('.')+1,value.length);
		//value = value.replace(/^[^\.]\./g, '');
		value = value.toLowerCase();
		return ext.include(value);
	},
	file : function(value)
	{
	},
	ip : function(value)
	{
		expression = this.getExpression('ip');
		return expression.test(value); 
	},
	minLength : function(value, min)
	{
		size = value.length; 
		return (size >= min); 
	},
	maxLength : function(value, max)
	{
		size = value.length; 
		return (size <= max); 
	},
	money : function(value)
	{
		expression = this.getExpression('money');
		return expression.test(value); 
	},
	multiple : function(value)
	{
	},
	numeric : function(value)
	{
		return !isNaN(value);
		//return Object.isNumber(value); 
	},
	postal : function(value)
	{
		expression = this.getExpression('postal');
		return expression.test(value); 
	},
	range : function(value, min, max)
	{
		if (!Object.isNumber(value))
			return false;
		if (!Object.isUndefined(min) && !Object.isUndefined(max))
		{
			if (min > max)
				return false;
			if (value > min && value < max)
				return true;
		}
		else if (isFinite(value))
			return true;
		return false; 
	},
	inList : function(value, array)
	{
		return array.include(value); 
	},
	userDefined : function(value, method)
	{
		return method(value); 
	}
});

Validation.Expressions = new Object(
{
	'email'        : /^[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?:[a-z]{2,4}|museum|travel)$/i,
	'alphaNumeric' : /^[a-z0-9]+$/i,
	'url'          : /^(?:(?:https?|ftps?|file|news|gopher):\/\/)?(?:(?:(?:25[0-5]|2[0-4]\d|(?:(?:1\d)?|[1-9]?)\d)\.){3}(?:25[0-5]|2[0-4]\d|(?:(?:1\d)?|[1-9]?)\d)|(?:[0-9a-z]{1}[0-9a-z\-]*\.)*(?:[0-9a-z]{1}[0-9a-z\-]{0,62})\.(?:[a-z]{2,6}|[a-z]{2}\.[a-z]{2,6})(?::[0-9]{1,4})?)(?:\/?|\/[\w\-\.,\'@?^=%&:;\/~\+#]*[\w\-\@?^=%&\/~\+#])$/i,
	'phone'        : /^([0]?[0-9]{2})[ \.\-]?[0-9]{4}[ \.\-]?[0-9]{4}$/,
	'cc'           : new Object(
	{
		'amex'     : /^3[4|7]\d{13}$/,
		'bankcard' : /^56(10\d\d|022[1-5])\d{10}$/,
		'diners'   : /^(?:3(0[0-5]|[68]\d)\d{11})|(?:5[1-5]\d{14})$/,
		'disc'     : /^(?:6011|650\d)\d{12}$/,
		'electron' : /^(?:417500|4917\d{2}|4913\d{2})\d{10}$/,
		'enroute'  : /^2(?:014|149)\d{11}$/,
		'jcb'      : /^(3\d{4}|2100|1800)\d{11}$/,
		'maestro'  : /^(?:5020|6\d{3})\d{12}$/,
		'mc'       : /^5[1-5]\d{14}$/,
		'solo'     : /^(6334[5-9][0-9]|6767[0-9]{2})\d{10}(\d{2,3})?$/,
		'switch'   : /^(?:49(03(0[2-9]|3[5-9])|11(0[1-2]|7[4-9]|8[1-2])|36[0-9]{2})\d{10}(\d{2,3})?)|(?:564182\d{10}(\d{2,3})?)|(6(3(33[0-4][0-9])|759[0-9]{2})\d{10}(\d{2,3})?)$/,
		'visa'     : /^4\d{12}(\d{3})?$/,
		'voyager'  : /^8699[0-9]{11}$/,
		'any'      : /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})$/
	}),
	'date'         : new Object(
	{
		'dmy'      : /^(?:(?:31(\/|-|\.|\x20)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/|-|\.|\x20)(?:0?[1,3-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/|-|\.|\x20)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/|-|\.|\x20)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/,
		'mdy'      : /^(?:(?:(?:0?[13578]|1[02])(\/|-|\.|\x20)31)\1|(?:(?:0?[13-9]|1[0-2])(\/|-|\.|\x20)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:0?2(\/|-|\.|\x20)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/|-|\.|\x20)(?:0?[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/,
		'ymd'      : /^(?:(?:(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\/|-|\.|\x20)(?:0?2\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\d)?\d{2})(\/|-|\.|\x20)(?:(?:(?:0?[13578]|1[02])\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\2(?:0?[1-9]|1\d|2[0-8]))))$/,
		'dMy'      : /^((31(?!\ (Feb(ruary)?|Apr(il)?|June?|(Sep(?=\b|t)t?|Nov)(ember)?)))|((30|29)(?!\ Feb(ruary)?))|(29(?=\ Feb(ruary)?\ (((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))|(0?[1-9])|1\d|2[0-8])\ (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\b|t)t?|Nov|Dec)(ember)?)\ ((1[6-9]|[2-9]\d)\d{2})$/,
		'Mdy'      : /^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sept|Nov|Dec)(ember)?)\ (0?[1-9]|([12]\d)|30))|(Feb(ruary)?\ (0?[1-9]|1\d|2[0-8]|(29(?=,?\ ((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\,?\ ((1[6-9]|[2-9]\d)\d{2}))$/,
		'My'       : /^(Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\b|t)t?|Nov|Dec)(ember)?)[ \/]((1[6-9]|[2-9]\d)\d{2})$/,
		'my'       : /^(((0[123456789]|10|11|12)([\- \/\.])(([1][9][0-9][0-9])|([2][0-9][0-9][0-9]))))$/
	}),
	'time'         : /^((0?[1-9]|1[012])(:[0-5]\d){0,2}[ ]?([AP]M|[ap]m))$|^([01]\d|2[0-3])(:[0-5]\d){0,2}$/,
	'decimal'      : /^[\-+]?[0-9]*\.{1}[0-9]+(?:[eE][-+]?[0-9]+)?$/,
	'ip'           : /^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/,
	'money'        : /^\$?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}[0-9]{0,}(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/,
	'postal'       : /\A\b[0-9]{5}(?:-[0-9]{4})?\b\z/i
});
